package com.dure.hotmemory.drawview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.dure.hotmemory.MainActivity;
import com.dure.hotmemory.scenes.BaseScene;
import com.dure.hotmemory.scenes.BgScene;
import com.dure.hotmemory.scenes.MainScene;
import com.dure.hotmemory.scenes.WelcomeScene;

import java.util.ArrayList;


/**
 * Created by zhanglong on 2016/11/1 17:11.
 * 主要用于控制scene的展现,暂停，切换，销毁
 */
public class UniverseView extends BaseSurfaceView {

    private BaseScene bgScene;// 用于绘制背景
    public BaseScene currentScene;// 用于绘制当前展示的scene
    private BaseScene oldScene;// 用于绘制即将消失的scene
    public ArrayList<BaseScene> sceneList = new ArrayList<>();

    private boolean moveTowardsLeft, moveTowardsRight;
    private float moveDistance;

    public long getDistanceStartTime, totalElapseTime;
    public float totalMoveDistance;
    Handler handler;

    public UniverseView(Context context) {
        super(context);
        initData();
    }

    public UniverseView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initData();
    }

    public UniverseView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initData();
    }

    public void initData() {
        bgScene = new BgScene(this);
//        currentScene = new MainScene(this);
//        currentScene = new WelcomeScene(this);
//        sceneList.add(currentScene);
        handler = new Handler();
    }


    @Override
    public void dataUpdate() {
        // 准备绘制背景的数据
        if (currentScene.isShowBg() && bgScene != null)
            bgScene.handleData();

        // 准备绘制上一个场景的数据
        if (oldScene != null && oldScene.isShowing()) {
            oldScene.handleData();
        }

        // 准备绘制当前场景的数据
        if (currentScene != null) {
            currentScene.handleData();
        }

        moveControll();
    }

    @Override
    public void drawUpdate(Canvas canvas) {
        if (currentScene.isShowBg() && bgScene != null)
            bgScene.handleDraw(canvas);

        if (oldScene != null && oldScene.isShowing()) {
            oldScene.handleDraw(canvas);
        }

        if (currentScene != null) {
            currentScene.handleDraw(canvas);
        }
    }


    public void setCurrentScene(BaseScene currentScene) {
        this.currentScene = currentScene;
        if (currentScene instanceof  WelcomeScene){
            return;
        }
        sceneList.add(currentScene);
        if (currentScene.sceneView != null) {
            currentScene.sceneView.setX(getWidth());
        }

        if (sceneList.size() > 1) {
            oldScene = sceneList.get(sceneList.size() - 2);
        } else {
            oldScene = null;
        }

        if (oldScene != null && oldScene.sceneView != null) {
            oldScene.sceneView.setX(0);
        }
    }

    public void moveToNewScene(BaseScene newScene) {
        setCurrentScene(newScene);

        if (oldScene != null)
            oldScene.setShowing(true);
        moveTowardsLeft = true;
    }

    public void backToLastScene() {
        currentScene.handleBack();
        if (oldScene != null)
            oldScene.setShowing(true);
        moveTowardsRight = true;

        if (currentScene.sceneView != null) {
            currentScene.sceneView.setX(0);
        }

        if (oldScene != null && oldScene.sceneView != null) {
            oldScene.sceneView.setX(-getWidth());
        }
    }


    public void setOldSceneToCurrentScene() {
        sceneList.remove(currentScene);
        if (currentScene.sceneView != null) {
            Log.d("lesleixz", "do remove");
            int childCount = ((MainActivity) baseActivity).parentFL.getChildCount();
            View view = ((MainActivity) baseActivity).parentFL.getChildAt(childCount - 1);
            ((MainActivity) baseActivity).parentFL.removeView(view);
        }
        if (oldScene != null) {
            currentScene = oldScene;
            currentScene.onRestart();

            if (sceneList.size() > 1) {
                oldScene = sceneList.get(sceneList.size() - 2);
                oldScene.setShowing(false);
            } else {
                oldScene = null;
            }
        }
    }


    public BaseScene getCurrentScene() {
        return currentScene;
    }


    public BaseScene getOldScene() {
        return oldScene;
    }


    // 通过时间来测量应该移动的距离
    // totalTime / totalDistance = (currentTime - startTime) / moveDistance
    public float getDistanceByTimeElapsed(int totalTime, float totalDistance) {

        if (getDistanceStartTime == 0) {
            getDistanceStartTime = System.currentTimeMillis();
        }

        long currentTime = System.currentTimeMillis();
        long deltaTime = currentTime - getDistanceStartTime;

        float moveDistance = 0;
        if (totalElapseTime + deltaTime >= totalTime) {// 当时间超过totalTime时， 只使用刚好到达totalTime那部分deltaTime来计算距离
            totalElapseTime = 0;

            // 直接把最后剩下的一点距离给moveDistance
            moveDistance = totalDistance - totalMoveDistance;
            totalMoveDistance = 0;
            getDistanceStartTime = 0;

        } else {
            totalElapseTime += deltaTime;
            moveDistance = deltaTime * (totalDistance / totalTime);
            totalMoveDistance += moveDistance;
            getDistanceStartTime = System.currentTimeMillis();
        }

        return moveDistance;
    }


    // 控制场景的移动
    public void moveControll() {
        if (moveTowardsLeft) {
            float deltaDistance = getDistanceByTimeElapsed(300, getWidth());
            if (moveDistance + deltaDistance < getWidth()) {
                moveDistance += deltaDistance;
            } else {
                moveTowardsLeft = false;
                deltaDistance = getWidth() - moveDistance;
                moveDistance = 0;
            }

            if (oldScene != null && oldScene.isShowing()) {
                if (oldScene.sceneView == null)
                    oldScene.left -= deltaDistance;
                else {
                    final float changeValue = deltaDistance;
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (oldScene != null && oldScene.sceneView != null) {
                                float viewX = oldScene.sceneView.getX();
                                oldScene.sceneView.setX(viewX - changeValue);

                            }
                        }
                    });

                }
            }
            if (currentScene.sceneView == null)
                currentScene.left -= deltaDistance;
            else {
                final float changeValue = deltaDistance;
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (currentScene != null && currentScene.sceneView != null) {
                            float viewX = currentScene.sceneView.getX();
                            currentScene.sceneView.setX(viewX - changeValue);
                            currentScene.sceneView.bringToFront();
                        }
                    }
                });

            }

            if (currentScene.isShowBg()) {
                bgScene.left += deltaDistance;
            }

            if (!moveTowardsLeft) {
                if (oldScene != null)
                    oldScene.setShowing(false);
                if (currentScene.sceneView != null) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            currentScene.sceneView.setX(0);
                        }
                    });
                }
            }

        } else if (moveTowardsRight) {// 返回运动
            float deltaDistance = getDistanceByTimeElapsed(300, getWidth());
            if (moveDistance + deltaDistance < getWidth()) {
                moveDistance += deltaDistance;
            } else {
                moveTowardsRight = false;
                deltaDistance = getWidth() - moveDistance;
                moveDistance = 0;


            }

            if (oldScene != null && oldScene.isShowing()) {
                if (oldScene.sceneView == null)
                    oldScene.left += deltaDistance;
                else {
                    final float changeValue = deltaDistance;
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (oldScene != null
                                    && oldScene.sceneView != null) {
                                if (currentScene.sceneView == null)// 当前view没有sceneView时必须调用此方法才会出现oldScene
                                    oldScene.sceneView.bringToFront();

                                float viewX = oldScene.sceneView.getX();
                                oldScene.sceneView.setX(viewX + changeValue);
                            }
                        }
                    });
                }
            }
            if (currentScene.sceneView == null)
                currentScene.left += deltaDistance;
            else {

                final float changeValue = deltaDistance;
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (currentScene != null && currentScene.sceneView != null) {
                            float viewX = currentScene.sceneView.getX();
                            currentScene.sceneView.setX(viewX + changeValue);
                        }
                    }
                });

            }
            if (currentScene.isShowBg()) {
                bgScene.left -= deltaDistance;
            }

            if (!moveTowardsRight) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        setOldSceneToCurrentScene();
                        if (currentScene.sceneView != null) {
                            currentScene.sceneView.setX(0);
                            currentScene.sceneView.bringToFront();
                        }
                    }
                });


            }
        }
    }

    @Override
    public void handleInputTouchEngage(PointF point) {
        currentScene.handleDown(point);
    }

    @Override
    public void handleInputTouchDrag(PointF point) {
        currentScene.handleMove(point);
    }

    @Override
    public void handleInputTouchRelease(PointF point) {
        currentScene.handleUp(point);
    }
}
